OptionMultiply = 5, onTicker = [], minutes = 1, secondsFinal = 30, firstSeconds = 30, updateMinutes = 3 * 60;
clockSecondsShow = 10;
$.isAjaxLance = 1;
$.onTickerleilao = {
    url: '',
    $minutes: minutes,
    $seconds: minutes * 60,
    $updatetime: 180

};

if (!window.Lances) {
    window.Lances = function () {
    };
    Lances.prototype = {
    };

}



add_banner_home = false;

function form_open(action, extra, method) {
    method = method || 'post';
    action = action || '#', extra = extra || '';
    return '<form method="' + method + '"  action="' + action + '"  ' + extra
            + '>';
}

function auto_formate_date(date, loc) {
    loc = loc || 'pt-br';

    var patter_db = /[0-9]{4}\-[0-9]{2}\-[0-9]{2}/gi, patter_dbtime = /[0-9]{4}\-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/gi;

    if (patter_dbtime.test(date)) {
        var array_dt = date.split(' '), subdate = array_dt['0'];
    } else if (patter_db.test(date)) {
        var subdate = date;
    }

    switch (loc) {
        case 'pt-br':
        default:
            return subdate.substring(8, 10) + '/' + subdate.substring(5, 7) + '/'
                    + subdate.substring(0, 4) + ' ' + array_dt['1'];
            break;

    }

}

function form_input(name, value, extra) {
    name = name || '';
    value = value || '';
    extra = extra || '';
    return '<input type="text"  name="' + name + '" value="' + value + '" '
            + extra + '/>';
}
function form_submit(name, value, extra) {
    name = name || '';
    value = value || '';
    extra = extra || '';
    return '<input type="submit"  name="' + name + '" value="' + value + '" '
            + extra + '/>';
}

function form_password(name, value, extra) {
    name = name || '';
    value = value || '';
    extra = extra || '';
    return '<input type="password" value="' + value + '" name="' + name + '" '
            + extra + '/>';
}

function form_radio(name, value, extra) {
    name = name || '';
    value = value || '';
    extra = extra || '';
    return '<input type="radio" value="' + value + '" name="' + name + '" '
            + extra + '/>';
}

function form_checkbox(name, value, extra) {
    name = name || '';
    value = value || '';
    extra = extra || '';
    return '<input type="checkbox" value="' + value + '" name="' + name + '" '
            + extra + '/>';
}
function form_hidden(name, value) {
    return '<input type="hidden"  value="' + value + '" name="' + name + '" />';
}
function form_label(data, id, extra) {
    data = data || '';
    id = id || data;
    extra = extra || '';
    return '<label for="' + id + '" ' + extra + ' >' + data + '</label>';
}

function form_dropdown(name, options, selected, extra) {
    var name = name || '', options = options || {}, selected = selected || '', extra = extra
            || '';

    var drop = '<select name="' + name + '" ' + extra + '>';
    for (var i in options) {
        var label = options[i], sel = selected == i ? 'selected' : '';
        drop += '<option value="' + i + '" ' + sel + '>' + label + '</option>';
    }
    drop += '</select>';

    return drop;
}

function form_textarea(name, data, extra) {
    var name = name || '', data = data || '', extra = extra || '';

    return '<textarea name="' + name + '" ' + extra + '>' + data
            + '</textarea>';
}

function form_close(extra) {
    var extra = extra || '';
    return '</form ' + extra + '>';
}

function split(val) {
    return val.split(/,\s*/);
}
function extractLast(term) {
    return split(term).pop();
}

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + bugfix by: Michael White (http://getsprink.com)
    // + bugfix by: Benjamin Lupton
    // + bugfix by: Allan Jensen (http://www.winternet.no)
    // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // + bugfix by: Howard Yeend
    // + revised by: Luke Smith (http://lucassmith.name)
    // + bugfix by: Diogo Resende
    // + bugfix by: Rival
    // + input by: Kheang Hok Chin (http://www.distantia.ca/)
    // + improved by: davook
    // + improved by: Brett Zamir (http://brett-zamir.me)
    // + input by: Jay Klehr
    // + improved by: Brett Zamir (http://brett-zamir.me)
    // + input by: Amir Habibi (http://www.residence-mixte.com/)
    // + bugfix by: Brett Zamir (http://brett-zamir.me)
    // + improved by: Theriault
    // + input by: Amirouche
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // * example 1: number_format(1234.56);
    // * returns 1: '1,235'
    // * example 2: number_format(1234.56, 2, ',', ' ');
    // * returns 2: '1 234,56'
    // * example 3: number_format(1234.5678, 2, '.', '');
    // * returns 3: '1234.57'
    // * example 4: number_format(67, 2, ',', '.');
    // * returns 4: '67,00'
    // * example 5: number_format(1000);
    // * returns 5: '1,000'
    // * example 6: number_format(67.311, 2);
    // * returns 6: '67.31'
    // * example 7: number_format(1000.55, 1);
    // * returns 7: '1,000.6'
    // * example 8: number_format(67000, 5, ',', '.');
    // * returns 8: '67.000,00000'
    // * example 9: number_format(0.9, 0);
    // * returns 9: '1'
    // * example 10: number_format('1.20', 2);
    // * returns 10: '1.20'
    // * example 11: number_format('1.20', 4);
    // * returns 11: '1.2000'
    // * example 12: number_format('1.2000', 3);
    // * returns 12: '1.200'
    // * example 13: number_format('1 000,50', 2, '.', ' ');
    // * returns 13: '100 050.00'
    // Strip all characters but numerical ones.
    number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
    var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0
            : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ','
            : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.'
            : dec_point, s = '', toFixedFix = function (n, prec) {
                var k = Math.pow(10, prec);
                return '' + Math.round(n * k) / k;
            };
    // Fix for IE parseFloat(0.55).toFixed(0) = 0;
    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}
lastValor = [];

function atualizeLancesPainelAtivos(url) {

    var url = url || false;
    // $('.ganhador-atual,.ganhadores-atual').text(' --- ');
    if (url !== false) {

        var data = [], sizeIntervalLance = $('[data-ativo-id]').size();
        $('[data-ativo-id]').each(function () {
            data.push($(this).attr('data-ativo-id'));
        });

        $('.ganhador-atual,.lance-atual,.ganhadores-atual').text(' --- ');
        return;
        var $$ajax = function () {
            $.ajax({
                url: url,
                dataType: 'json',
                type: 'post',
                async: false,
                success: function (jsdata) {
                    var data = jsdata.data;
                    // lancesAutomaticos();
                    for (var i in data) {
                        var row = data[i];
                        $('[data-lote-id="' + row.ID + '"]').each(function () {
                            updateBox(this, row);
                        });
                    }


                }
            });
        };

        setTimeout(function () {

            $$ajax();

        }, 3000);
    }

}

function updateBox(obj, options) {
    var options = options || {}, old_value = $(obj).find('.label-ganhador')
            .text(), objGanhador = $(obj).find('.label-ganhador'),
            new_value = options.LOGIN,
            $obj = $('[data-lote-id="' + options.ID + '"]');

    options.LOGIN = options.LOGIN + (options.TIPO == 'A' ? '(A)' : '');

    objGanhador.html('<span class="itext">' + options.LOGIN + '</span>');
    if (old_value !== '' && old_value !== options.LOGIN) {
        var $w = objGanhador.outerWidth(), $$w = objGanhador.width(), $h = objGanhador
                .outerHeight();

        $('<span class="new-ganhador" style="display:none;" ></span>').css({
            'width': $w,
            'height': $h
        }).appendTo(objGanhador).fadeIn('slow').delay(900).fadeOut('slow',
                function () {
                    $(this).remove();
                });
    }
    $obj.find('.painel-info-num-lances  span').text(new Number(options.LANCES));
    var $id = $(obj).attr('data-lote-id');

    $('[data-next-price-id="' + $id + '"]').text(options.NEXT_PRICE);

    var objPanel = $('.maxlive-ul-li[data-lote-id="' + $id + '"]'),
            old_id = obj.attr('user-lote');

    if (old_id != options.USER_ID && old_id != 0) {

        //if(objPanel.find('.hasNewSeller').size() == 0){
        animateObj(objPanel);
        //}
    }
    obj.attr('user-lote', options.USER_ID);

    $(obj).find('.label-lance-ganhador').text(options.VALOR);
    $('[data-next-price-id="' + $id + '"]').text(options.NEXT_PRICE);
    $('[data-lote-id="' + $id + '"] .count-num-lances-lote').text(new Number(options.LANCES));
    //count-num-compradores-lote
    $('[data-lote-id="' + $id + '"] .count-num-compradores-lote').text(new Number(options.COMPRADORES));
    if (options.RESET == true) {
        $('[data-lote-id="' + $id + '"]').find('.btn-lance-aut').removeClass('on');
        $('[data-lote-id="' + $id + '"]').find('.bid-click').removeClass('is-active');
    }
    var path = /hide/gi,
            ishide = $('[data-lote-id="' + $id + '"] .blocked-lance');
    if (options.ENABLED_LANCE_AUTO == false && ishide.css('display') != 'none') {
        //console.log(ishide.attr('class'));
        ishide.addClass('hide');
        $('[data-lote-id="' + $id + '"]').removeData('data');
        $('[data-lote-id="' + $id + '"] .btn-lance-aut').removeClass('on');
        $('[data-lote-id="' + $id + '"] .bid-click').removeClass('is-active');
    }

    //date('Y-m-d H:i:s',options.TIME)

    var $time = $obj.data('_time');
    if ($time != undefined) {
        $time.$last_date = options.TIME;
        $obj.data('_time', $time);
        //console.log($time);
    }
}


function animateObj(obj) {

    var end = false;

    $(obj).data('cont', 24);

    var has_clock = $(obj).find('.iclock-painel').size();

    if (has_clock === 0) {
        //  $(obj).append('<span class="iclock-painel"></span>')
    }
    $animate = function () {
        var $anim = $(obj).data('cont'),
                $obj = $(obj),
                $time = $obj.data('_time');

        if ($anim % 2 == 0) {
            obj.find('.box-lote-maxlive').addClass('new_lance_user');
            if ($time != undefined) {
                if ($time.$seconds < secondsFinal)
                    obj.find('.box-lote-maxlive').addClass('on-red');
            }
        } else {
            obj.find('.box-lote-maxlive').removeClass('new_lance_user').removeClass('on-red');
        }

        $anim -= 1;
        $(obj).data('cont', $anim);
        if ($anim < 1) {
            clearInterval($ins);
            obj.find('.box-lote-maxlive').removeClass('new_lance_user').removeClass('on-red');
            // $(obj).find('.iclock-painel').remove();
        }


    };
    var $ins = setInterval($animate, 300);


}
function lancesAutomaticos() {
    /*
     $.ajax({
     url: url_site + 'home/autoLance/' + ID_LEILAO,
     dataType: 'json',
     type: 'post',
     // async: false,
     success: function(jsdata) {
     var data = jsdata.data;
     
     
     
     }
     });*/
}

function atualizeLastTime() {

    $('.clock-count-down,.clock-count-ativo-single').each(function () {

    });

}

function converte_data_object(str) {

    var str = str || false, nt = new Date(), pattern = /[0-9]{4}\-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/gi;

    if (str) {

        if (pattern.test(str)) {
            var str_array = str.split(' '), hours = str_array['1'].split(':'), dates = str_array['0']
                    .split('-');

            nt.setFullYear(dates['0']);
            nt.setMonth(dates['1']);
            nt.setDate(dates['2']);
            nt.setSeconds(hours['2']);
            nt.setMinutes(hours['1']);
            nt.setHours(hours['0']);
        }

    }

    return {
        year: nt.getFullYear(),
        month: nt.getMonth(),
        day: nt.getDate(),
        seconds: nt.getSeconds(),
        minutes: nt.getMinutes(),
        hours: nt.getHours(),
        time: nt.getTime()
    }

}

function atualizeLancesPainel(url) {

    $.onTickerleilao.url = url || false;
    $('.ganhador-atual,.ganhadores-atual').text(' --- ');


    if (url !== false) {

        dataOnTickerLeilao = [],
                sizeIntervalLance = $('[data-lote-id]').size(), ids = [];
        $('[data-lote-id]').each(function () {

            var $id = $(this).attr('data-lote-id');

            if (!in_array($id, dataOnTickerLeilao))
                dataOnTickerLeilao.push($id);
            // ids.push($(this).attr('data-id'));
            // adicionando o id do ativo ao ticker de contagem

        });
        if (sizeIntervalLance > 0) {
            $('.ganhador-atual,.ganhadores-atual').text(' --- ');
            ajaxData();
        }
    }
}


function in_array(needle, haystack, argStrict) {
    //  discuss at: http://phpjs.org/functions/in_array/
    // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // improved by: vlado houba
    // improved by: Jonas Sciangula Street (Joni2Back)
    //    input by: Billy
    // bugfixed by: Brett Zamir (http://brett-zamir.me)
    //   example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);
    //   returns 1: true
    //   example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
    //   returns 2: false
    //   example 3: in_array(1, ['1', '2', '3']);
    //   example 3: in_array(1, ['1', '2', '3'], false);
    //   returns 3: true
    //   returns 3: true
    //   example 4: in_array(1, ['1', '2', '3'], true);
    //   returns 4: false

    var key = '',
            strict = !!argStrict;

    //we prevent the double check (strict && arr[key] === ndl) || (!strict && arr[key] == ndl)
    //in just one for, in order to improve the performance 
    //deciding wich type of comparation will do before walk array
    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;
            }
        }
    } else {
        for (key in haystack) {
            if (haystack[key] == needle) {
                return true;
            }
        }
    }

    return false;
}
function ajaxData() {



    $.ajax({
        url: $.onTickerleilao.url,
        dataType: 'json',
        type: 'post',
        //async:false,

        data: {
            lotes: dataOnTickerLeilao
        },
        success: function (data) {
            var $data = data.data;
            for (var i in $data) {
                var row = $data[i];
                obj = $('[data-lote-id="' + row.ID + '"]');
                updateBox(obj, row);

            }
            if (data.num_rows > 0) {
                //lancesAutomaticos();
            }
            return;
            /*
             if (jsdata.error === false) {
             var data = jsdata.data;
             for (var i in data) {
             var id = data[i].lote, total = data[i].total, compradores = data[i].compradores, is_comp = data[i].comprador, is_update = data[i].is_update, time = data[i].time, is_time = data[i].data, new_bid = data[i].new_bid, user = data[i].user, bid_id = data[i].bid_id, bid_value = data[i].bid_value, hora_shop = data[i].hora_shop, bid_taxa = data[i].bid_taxa, eleLogin = $('[ganhador-atual-data="'
             + bid_id + '"]'), eleLoginOf = eleLogin
             .offset();
             
             $('[lance-atual-data="' + bid_id + '"]').text(
             'R$ '
             + number_format(bid_value, 2, ',',
             '.'));
             eleLogin.html('<div class="label-login-lance">'
             + user + '</div>');
             
             if (new_bid !== false) {
             $('<div class="new-lance"></div>').appendTo(
             eleLogin).css(
             {
             width: (eleLogin.width() + 4)
             + 'px',
             height: (eleLogin.height() + 4)
             + 'px',
             marginTop: '-'
             + (eleLogin.height() + 2)
             + 'px',
             marginLeft: '-2px',
             display: 'none'
             
             }).fadeIn(500, function() {
             $(this).fadeOut(500, function() {
             $(this).remove();
             });
             });
             
             }
             
             $('[num-lances-atual-data="' + bid_id + '"]').text(
             ' ' + total + ' Lances ');
             $('[ganhadores-atual-data="' + bid_id + '"]').html(
             ' ' + compradores);
             if (is_comp === true) {
             
             $('[lance-box-data="' + bid_id + '"]').html(
             data[i].consignado
             + 'FECHADO : <strong>'
             + auto_formate_date(hora_shop)
             + '</strong>'
             + '<hr/>'
             + 'GANHADOR : <strong>'
             + user
             + '</strong>'
             + '<hr/>'
             + 'LANCE : <strong> R$ '
             + number_format(bid_value, 2,
             ',', '.') + ' + ('
             + bid_taxa + '%) </strong>'
             + '<hr/>'
             + 'LANCES USADOS : <strong> '
             + data[i].lances_by_user
             + '  </strong>');
             }
             $.onTickerleilao.tickers[bid_id] = false;
             if (is_update) {
             $.onTickerleilao.tickers[bid_id] = is_time;
             }
             
             }
             
             }*/

        },
        complete: function (e) {
            //console.log(e.status);
            //console.log($.onTickerleilao);
            if (e.status == 200) {
                ajaxData();
            }
            //ajaxData();
        }
    });

    //setTimeout(ajaxData, 1000);
    //setTimeout(lancesAutomaticos,2000);

}

// functions php
function date(format, timestamp) {
    // http://kevin.vanzonneveld.net
    // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + improved by: MeEtc (http://yass.meetcweb.com)
    // + improved by: Brad Touesnard
    // + improved by: Tim Wiel
    // + improved by: Bryan Elliott
    // + improved by: David Randall
    // + input by: Brett Zamir (http://brett-zamir.me)
    // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + improved by: Theriault
    // + derived from: gettimeofday
    // + input by: majak
    // + bugfixed by: majak
    // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + input by: Alex
    // + bugfixed by: Brett Zamir (http://brett-zamir.me)
    // + improved by: Theriault
    // + improved by: Brett Zamir (http://brett-zamir.me)
    // + improved by: Theriault
    // + improved by: Thomas Beaucourt (http://www.webapp.fr)
    // + improved by: JT
    // + improved by: Theriault
    // + improved by: Rafał Kukawski (http://blog.kukawski.pl)
    // + bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
    // + input by: Martin
    // + input by: Alex Wilson
    // + input by: Haravikk
    // + improved by: Theriault
    // + bugfixed by: Chris (http://www.devotis.nl/)
    // % note 1: Uses global: php_js to store the default timezone
    // % note 2: Although the function potentially allows timezone info (see
    // notes), it currently does not set
    // % note 2: per a timezone specified by date_default_timezone_set().
    // Implementers might use
    // % note 2: this.php_js.currentTimezoneOffset and
    // this.php_js.currentTimezoneDST set by that function
    // % note 2: in order to adjust the dates in this function (or our other
    // date functions!) accordingly
    // * example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // * returns 1: '09:09:40 m is month'
    // * example 2: date('F j, Y, g:i a', 1062462400);
    // * returns 2: 'September 2, 2003, 2:26 am'
    // * example 3: date('Y W o', 1062462400);
    // * returns 3: '2003 36 2003'
    // * example 4: x = date('Y m d', (new Date()).getTime()/1000);
    // * example 4: (x+'').length == 10 // 2009 01 09
    // * returns 4: true
    // * example 5: date('W', 1104534000);
    // * returns 5: '53'
    // * example 6: date('B t', 1104534000);
    // * returns 6: '999 31'
    // * example 7: date('W U', 1293750000.82); // 2010-12-31
    // * returns 7: '52 1293750000'
    // * example 8: date('W', 1293836400); // 2011-01-01
    // * returns 8: '52'
    // * example 9: date('W Y-m-d', 1293974054); // 2011-01-02
    // * returns 9: '52 2011-01-02'
    var that = this, jsdate, f,
            // Keep this here (works, but for code commented-out
            // below for file size reasons)
            // , tal= [],
            txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur",
                "January", "February", "March", "April", "May", "June", "July",
                "August", "September", "October", "November", "December"],
            // trailing backslash -> (dropped)
            // a backslash followed by any character (including backslash) -> the
            // character
            // empty string -> empty string
            formatChr = /\\?(.?)/gi, formatChrCb = function (t, s) {
                return f[t] ? f[t]() : s;
            }, _pad = function (n, c) {
        n = String(n);
        while (n.length < c) {
            n = '0' + n;
        }
        return n;
    };
    f = {
        // Day
        d: function () { // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function () { // Shorthand day name; Mon...Sun
            return f.l().slice(0, 3);
        },
        j: function () { // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function () { // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function () { // Ordinal suffix for day of month; st, nd, rd, th
            var j = f.j(), i = j % 10;
            if (i <= 3 && parseInt((j % 100) / 10, 10) == 1) {
                i = 0;
            }
            return ['st', 'nd', 'rd'][i - 1] || 'th';
        },
        w: function () { // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function () { // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j()), b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5);
        },
        // Week
        W: function () { // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3), b = new Date(
                    a.getFullYear(), 0, 4);
            return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
        },
        // Month
        F: function () { // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function () { // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function () { // Shorthand month name; Jan...Dec
            return f.F().slice(0, 3);
        },
        n: function () { // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function () { // Days in month; 28...31
            return (new Date(f.Y(), f.n(), 0)).getDate();
        },
        // Year
        L: function () { // Is leap year?; 0 or 1
            var j = f.Y();
            return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0;
        },
        o: function () { // ISO-8601 year
            var n = f.n(), W = f.W(), Y = f.Y();
            return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
        },
        Y: function () { // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function () { // Last two digits of year; 00...99
            return f.Y().toString().slice(-2);
        },
        // Time
        a: function () { // am or pm
            return jsdate.getHours() > 11 ? "pm" : "am";
        },
        A: function () { // AM or PM
            return f.a().toUpperCase();
        },
        B: function () { // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2,
                    // Hours
                    i = jsdate.getUTCMinutes() * 60,
                    // Minutes
                    s = jsdate.getUTCSeconds(); // Seconds
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function () { // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function () { // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function () { // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function () { // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function () { // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function () { // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function () { // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },
        // Timezone
        e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
            /*
             * return that.date_default_timezone_get();
             */
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function () { // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0),
                    // Jan 1
                    c = Date.UTC(f.Y(), 0),
                    // Jan 1 UTC
                    b = new Date(f.Y(), 6),
                    // Jul 1
                    d = Date.UTC(f.Y(), 6); // Jul 1 UTC
            return ((a - c) !== (b - d)) ? 1 : 0;
        },
        O: function () { // Difference to GMT in hour format; e.g. +0200
            var tzo = jsdate.getTimezoneOffset(), a = Math.abs(tzo);
            return (tzo > 0 ? "-" : "+")
                    + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
        },
        P: function () { // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return (O.substr(0, 3) + ":" + O.substr(3, 2));
        },
        T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
            // The following works, but requires inclusion of the very
            // large timezone_abbreviations_list() function.
            /*
             * var abbr = '', i = 0, os = 0, default = 0; if (!tal.length) { tal =
             * that.timezone_abbreviations_list(); } if (that.php_js &&
             * that.php_js.default_timezone) { default =
             * that.php_js.default_timezone; for (abbr in tal) { for (i=0; i <
             * tal[abbr].length; i++) { if (tal[abbr][i].timezone_id ===
             * default) { return abbr.toUpperCase(); } } } } for (abbr in tal) {
             * for (i = 0; i < tal[abbr].length; i++) { os =
             * -jsdate.getTimezoneOffset() * 60; if (tal[abbr][i].offset === os) {
             * return abbr.toUpperCase(); } } }
             */
            return 'UTC';
        },
        Z: function () { // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },
        // Full Date/Time
        c: function () { // ISO-8601 date.
            return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function () { // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function () { // Seconds since UNIX epoch
            return jsdate / 1000 | 0;
        }
    };
    this.date = function (format, timestamp) {
        that = this;
        jsdate = (timestamp === undefined ? new Date() : // Not provided
                (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
                new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
                );

        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}

function mktime() {
    // http://kevin.vanzonneveld.net
    // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + improved by: baris ozdil
    // + input by: gabriel paderni
    // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + improved by: FGFEmperor
    // + input by: Yannoo
    // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + input by: jakes
    // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // + bugfixed by: Marc Palau
    // + improved by: Brett Zamir (http://brett-zamir.me)
    // + input by: 3D-GRAF
    // + bugfixed by: Brett Zamir (http://brett-zamir.me)
    // + input by: Chris
    // + revised by: Theriault
    // % note 1: The return values of the following examples are
    // % note 1: received only if your system's timezone is UTC.
    // * example 1: mktime(14, 10, 2, 2, 1, 2008);
    // * returns 1: 1201875002
    // * example 2: mktime(0, 0, 0, 0, 1, 2008);
    // * returns 2: 1196467200
    // * example 3: make = mktime();
    // * example 3: td = new Date();
    // * example 3: real = Math.floor(td.getTime() / 1000);
    // * example 3: diff = (real - make);
    // * results 3: diff < 5
    // * example 4: mktime(0, 0, 0, 13, 1, 1997)
    // * returns 4: 883612800
    // * example 5: mktime(0, 0, 0, 1, 1, 1998)
    // * returns 5: 883612800
    // * example 6: mktime(0, 0, 0, 1, 1, 98)
    // * returns 6: 883612800
    // * example 7: mktime(23, 59, 59, 13, 0, 2010)
    // * returns 7: 1293839999
    // * example 8: mktime(0, 0, -1, 1, 1, 1970)
    // * returns 8: -1
    var d = new Date(), r = arguments, i = 0, e = ['Hours', 'Minutes',
        'Seconds', 'Month', 'Date', 'FullYear'];

    for (i = 0; i < e.length; i++) {
        if (typeof r[i] === 'undefined') {
            r[i] = d['get' + e[i]]();
            r[i] += (i === 3); // +1 to fix JS months.
        } else {
            r[i] = parseInt(r[i], 10);
            if (isNaN(r[i])) {
                return false;
            }
        }
    }

    // Map years 0-69 to 2000-2069 and years 70-100 to 1970-2000.
    r[5] += (r[5] >= 0 ? (r[5] <= 69 ? 2e3 : (r[5] <= 100 ? 1900 : 0)) : 0);

    // Set year, month (-1 to fix JS months), and date.
    // !This must come before the call to setHours!
    d.setFullYear(r[5], r[3] - 1, r[4]);

    // Set hours, minutes, and seconds.
    d.setHours(r[0], r[1], r[2]);

    // Divide milliseconds by 1000 to return seconds and drop decimal.
    // Add 1 second if negative or it'll be off from PHP by 1 second.
    return (d.getTime() / 1e3 >> 0) - (d.getTime() < 0);
}


function strtotime(text, now) {
    //  discuss at: http://phpjs.org/functions/strtotime/
    //     version: 1109.2016
    // original by: Caio Ariede (http://caioariede.com)
    // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // improved by: Caio Ariede (http://caioariede.com)
    // improved by: A. Matías Quezada (http://amatiasq.com)
    // improved by: preuter
    // improved by: Brett Zamir (http://brett-zamir.me)
    // improved by: Mirko Faber
    //    input by: David
    // bugfixed by: Wagner B. Soares
    // bugfixed by: Artur Tchernychev
    //        note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
    //   example 1: strtotime('+1 day', 1129633200);
    //   returns 1: 1129719600
    //   example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
    //   returns 2: 1130425202
    //   example 3: strtotime('last month', 1129633200);
    //   returns 3: 1127041200
    //   example 4: strtotime('2009-05-04 08:30:00 GMT');
    //   returns 4: 1241425800

    var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false;

    if (!text) {
        return fail;
    }

    // Unecessary spaces
    text = text.replace(/^\s+|\s+$/g, '')
            .replace(/\s{2,}/g, ' ')
            .replace(/[\t\r\n]/g, '')
            .toLowerCase();

    // in contrast to php, js Date.parse function interprets:
    // dates given as yyyy-mm-dd as in timezone: UTC,
    // dates with "." or "-" as MDY instead of DMY
    // dates with two-digit years differently
    // etc...etc...
    // ...therefore we manually parse lots of common date formats
    match = text.match(
            /^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/);

    if (match && match[2] === match[4]) {
        if (match[1] > 1901) {
            switch (match[2]) {
                case '-':
                { // YYYY-M-D
                    if (match[3] > 12 || match[5] > 31) {
                        return fail;
                    }

                    return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
                case '.':
                { // YYYY.M.D is not parsed by strtotime()
                    return fail;
                }
                case '/':
                { // YYYY/M/D
                    if (match[3] > 12 || match[5] > 31) {
                        return fail;
                    }

                    return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
            }
        } else if (match[5] > 1901) {
            switch (match[2]) {
                case '-':
                { // D-M-YYYY
                    if (match[3] > 12 || match[1] > 31) {
                        return fail;
                    }

                    return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
                case '.':
                { // D.M.YYYY
                    if (match[3] > 12 || match[1] > 31) {
                        return fail;
                    }

                    return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
                case '/':
                { // M/D/YYYY
                    if (match[1] > 12 || match[3] > 31) {
                        return fail;
                    }

                    return new Date(match[5], parseInt(match[1], 10) - 1, match[3],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
            }
        } else {
            switch (match[2]) {
                case '-':
                { // YY-M-D
                    if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) {
                        return fail;
                    }

                    year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1];
                    return new Date(year, parseInt(match[3], 10) - 1, match[5],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
                case '.':
                { // D.M.YY or H.MM.SS
                    if (match[5] >= 70) { // D.M.YY
                        if (match[3] > 12 || match[1] > 31) {
                            return fail;
                        }

                        return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
                                match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                    }
                    if (match[5] < 60 && !match[6]) { // H.MM.SS
                        if (match[1] > 23 || match[3] > 59) {
                            return fail;
                        }

                        today = new Date();
                        return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
                                match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000;
                    }

                    return fail; // invalid format, cannot be parsed
                }
                case '/':
                { // M/D/YY
                    if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) {
                        return fail;
                    }

                    year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5];
                    return new Date(year, parseInt(match[1], 10) - 1, match[3],
                            match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
                }
                case ':':
                { // HH:MM:SS
                    if (match[1] > 23 || match[3] > 59 || match[5] > 59) {
                        return fail;
                    }

                    today = new Date();
                    return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
                            match[1] || 0, match[3] || 0, match[5] || 0) / 1000;
                }
            }
        }
    }

    // other formats and "now" should be parsed by Date.parse()
    if (text === 'now') {
        return now === null || isNaN(now) ? new Date()
                .getTime() / 1000 | 0 : now | 0;
    }
    if (!isNaN(parsed = Date.parse(text))) {
        return parsed / 1000 | 0;
    }

    date = now ? new Date(now * 1000) : new Date();
    days = {
        'sun': 0,
        'mon': 1,
        'tue': 2,
        'wed': 3,
        'thu': 4,
        'fri': 5,
        'sat': 6
    };
    ranges = {
        'yea': 'FullYear',
        'mon': 'Month',
        'day': 'Date',
        'hou': 'Hours',
        'min': 'Minutes',
        'sec': 'Seconds'
    };

    function lastNext(type, range, modifier) {
        var diff, day = days[range];

        if (typeof day !== 'undefined') {
            diff = day - date.getDay();

            if (diff === 0) {
                diff = 7 * modifier;
            } else if (diff > 0 && type === 'last') {
                diff -= 7;
            } else if (diff < 0 && type === 'next') {
                diff += 7;
            }

            date.setDate(date.getDate() + diff);
        }
    }

    function process(val) {
        var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes
                type = splt[0],
                range = splt[1].substring(0, 3),
                typeIsNumber = /\d+/.test(type),
                ago = splt[2] === 'ago',
                num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1);

        if (typeIsNumber) {
            num *= parseInt(type, 10);
        }

        if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) {
            return date['set' + ranges[range]](date['get' + ranges[range]]() + num);
        }

        if (range === 'wee') {
            return date.setDate(date.getDate() + (num * 7));
        }

        if (type === 'next' || type === 'last') {
            lastNext(type, range, num);
        } else if (!typeIsNumber) {
            return false;
        }

        return true;
    }

    times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' +
            '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' +
            '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)';
    regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?';

    match = text.match(new RegExp(regex, 'gi'));
    if (!match) {
        return fail;
    }

    for (i = 0, len = match.length; i < len; i++) {
        if (!process(match[i])) {
            return fail;
        }
    }

    // ECMAScript 5 only
    // if (!match.every(process))
    //    return false;

    return (date.getTime() / 1000);
}




function trim(str, charlist) {
    //  discuss at: http://phpjs.org/functions/trim/
    // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // improved by: mdsjack (http://www.mdsjack.bo.it)
    // improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
    // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // improved by: Steven Levithan (http://blog.stevenlevithan.com)
    // improved by: Jack
    //    input by: Erkekjetter
    //    input by: DxGx
    // bugfixed by: Onno Marsman
    //   example 1: trim('    Kevin van Zonneveld    ');
    //   returns 1: 'Kevin van Zonneveld'
    //   example 2: trim('Hello World', 'Hdle');
    //   returns 2: 'o Wor'
    //   example 3: trim(16, 1);
    //   returns 3: 6

    var whitespace, l = 0,
            i = 0;
    str += '';

    if (!charlist) {
        // default list
        whitespace =
                ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
    } else {
        // preg_quote custom list
        charlist += '';
        whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
    }

    l = str.length;
    for (i = 0; i < l; i++) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(i);
            break;
        }
    }

    l = str.length;
    for (i = l - 1; i >= 0; i--) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(0, i + 1);
            break;
        }
    }

    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}